diff options
Diffstat (limited to 'app/api/data-room/[projectId]/route.ts')
| -rw-r--r-- | app/api/data-room/[projectId]/route.ts | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/app/api/data-room/[projectId]/route.ts b/app/api/data-room/[projectId]/route.ts new file mode 100644 index 00000000..643dcf0f --- /dev/null +++ b/app/api/data-room/[projectId]/route.ts @@ -0,0 +1,118 @@ +// app/api/data-room/[projectId]/route.ts +import { NextRequest, NextResponse } from 'next/server'; +import { getServerSession } from 'next-auth/next'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route' +import { FileService, type FileAccessContext } from '@/lib/services/fileService'; +import { z } from 'zod'; + +// 파일 생성 스키마 검증 +const createFileSchema = z.object({ + name: z.string().min(1).max(255), + type: z.enum(['file', 'folder']), + parentId: z.string().uuid().optional().nullable(), + category: z.enum(['public', 'restricted', 'confidential', 'internal']).default('confidential'), + mimeType: z.string().optional(), + size: z.number().optional(), + filePath: z.string().optional(), +}); + +// 파일 목록 조회 +export async function GET( + request: NextRequest, + { params }: { params: { projectId: string } } +) { + try { + const session = await getServerSession(authOptions); + if (!session?.user) { + return NextResponse.json({ error: '인증이 필요합니다' }, { status: 401 }); + } + + const searchParams = request.nextUrl.searchParams; + const parentId = searchParams.get('parentId'); + const viewMode = searchParams.get('viewMode'); // 'tree' or 'grid' + const includeAll = searchParams.get('includeAll') === 'true'; // 전체 목록 가져오기 + + const context: FileAccessContext = { + userId: Number(session.user.id), + userDomain: session.user.domain || 'partners', + userEmail: session.user.email, + ipAddress: request.ip || request.headers.get('x-forwarded-for') || undefined, + userAgent: request.headers.get('user-agent') || undefined, + }; + + const fileService = new FileService(); + + // viewMode가 tree이거나 includeAll이 true인 경우 전체 목록 가져오기 + const files = await fileService.getFileList( + params.projectId, + parentId, + context, + { + includeAll: viewMode === 'tree' || includeAll + } + ); + + return NextResponse.json(files); + } catch (error) { + console.error('파일 목록 조회 오류:', error); + return NextResponse.json( + { error: '파일 목록을 불러올 수 없습니다' }, + { status: 500 } + ); + } +} + +// 파일/폴더 생성 +export async function POST( + request: NextRequest, + { params }: { params: { projectId: string } } +) { + try { + const session = await getServerSession(authOptions); + if (!session?.user) { + return NextResponse.json({ error: '인증이 필요합니다' }, { status: 401 }); + } + + const body = await request.json(); + const validatedData = createFileSchema.parse(body); + + const context: FileAccessContext = { + userId: Number(session.user.id), + userDomain: session.user.domain || 'partners', + userEmail: session.user.email, + ipAddress: request.ip || request.headers.get('x-forwarded-for') || undefined, + userAgent: request.headers.get('user-agent') || undefined, + }; + + const fileService = new FileService(); + const newFile = await fileService.createFileItem( + { + ...validatedData, + projectId: params.projectId, + }, + context + ); + + return NextResponse.json(newFile, { status: 201 }); + } catch (error) { + if (error instanceof z.ZodError) { + return NextResponse.json( + { error: '잘못된 요청 데이터', details: error.errors }, + { status: 400 } + ); + } + + if (error instanceof Error && error.message === '권한이 없습니다') { + return NextResponse.json( + { error: '파일 생성 권한이 없습니다' }, + { status: 403 } + ); + } + + console.error('파일 생성 오류:', error); + return NextResponse.json( + { error: '파일 생성에 실패했습니다' }, + { status: 500 } + ); + } +}
\ No newline at end of file |
